﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace JustTank
{
    public class ConsoleRenderer : IRenderer
    {
        int renderContextMatrixRows;
        int renderContextMatrixCols;
        char[,] renderContextMatrix;
        //TODO
        Dictionary<string, ObjectsColors> objectsColors;

        public ConsoleRenderer(int visibleConsoleRows, int visibleConsoleCols)
        {
            renderContextMatrix = new char[visibleConsoleRows, visibleConsoleCols];

            this.renderContextMatrixRows = renderContextMatrix.GetLength(0);
            this.renderContextMatrixCols = renderContextMatrix.GetLength(1);

            //TODO
            this.objectsColors = new Dictionary<string, ObjectsColors>();

            this.ClearQueue();
        }

        public void EnqueueForRendering(IRenderable obj)
        {
            char[,] objImage = obj.GetImage();

            int imageRows = objImage.GetLength(0);
            int imageCols = objImage.GetLength(1);

            MatrixCoords objTopLeft = obj.GetTopLeft();

            int lastRow = Math.Min(objTopLeft.Row + imageRows, this.renderContextMatrixRows);
            int lastCol = Math.Min(objTopLeft.Col + imageCols, this.renderContextMatrixCols);

            for (int row = obj.GetTopLeft().Row; row < lastRow; row++)
            {
                for (int col = obj.GetTopLeft().Col; col < lastCol; col++)
                {
                    if (row >= 0 && row < renderContextMatrixRows &&
                        col >= 0 && col < renderContextMatrixCols)
                    {
                        renderContextMatrix[row, col] = objImage[row - obj.GetTopLeft().Row, col - obj.GetTopLeft().Col];
                        this.objectsColors[row.ToString() + ":" + col.ToString()] = new ObjectsColors(renderContextMatrix[row, col], GetObjectColor(obj));
                    }
                }
            }
        }

        //TODO
        private ConsoleColor GetObjectColor(IRenderable obj)
        {
            if (obj is TankBot)
            {
                return (obj as TankBot).Color;
            }
            if (obj is TankHuman)
            {
                return (obj as TankHuman).Color;
            }
            if (obj is Bullet)
            {
                return (obj as Bullet).Color;
            }
            if (obj is IndestructibleBlock)
            {
                return (obj as IndestructibleBlock).Color;
            }
            return ConsoleColor.DarkGreen;
        }

        public void RenderAll()
        {
            Console.SetCursorPosition(0, 0);
            Console.BackgroundColor = ConsoleColor.Black;

            for (int row = 0; row < this.renderContextMatrixRows; row++)
            {
                for (int col = 0; col < this.renderContextMatrixCols; col++)
                {
                    string key = row.ToString() + ":" + col.ToString();
                    Console.ForegroundColor = this.objectsColors[key].Color;
                    Console.Write(this.objectsColors[key].Shape);
                }

                Console.Write(Environment.NewLine);
            }

            Console.WriteLine(Environment.NewLine);

        }

        public void ClearQueue()
        {
            //TODO
            this.objectsColors = new Dictionary<string, ObjectsColors>();

            for (int row = 0; row < this.renderContextMatrixRows; row++)
            {
                for (int col = 0; col < this.renderContextMatrixCols; col++)
                {
                    this.renderContextMatrix[row, col] = ' ';
                    //TODO
                    this.objectsColors.Add(row.ToString() + ":" + col.ToString(), new ObjectsColors(renderContextMatrix[row, col], ConsoleColor.Black));
                }
            }
        }

        //TODOB
        private class ObjectsColors
        {
            public char Shape;
            public ConsoleColor Color;
            public ObjectsColors(char pShape, ConsoleColor pColor)
            {
                this.Color = pColor;
                this.Shape = pShape;
            }
        }
    }
}
